//
//  GamePlayManager.cpp
//  popstar
//
//  Created by luyuhuang on 14/11/29.
//
//

#include "GamePlayManager.h"
#include "Star.h"
#include <ctime>
#include <iostream>

 GamePlayManager* GamePlayManager::create(GamePlayLayer *layer)
{
    
    GamePlayManager *pRet = new GamePlayManager();
    if (pRet && pRet->init())
    {
        pRet->autorelease();
        
        pRet->m_layer = layer;
        
        pRet->initMatrix(); // 初始化数姐
        
        
        return pRet;
    }
    else
    {
        delete pRet;
        pRet = NULL;
        return NULL;
    }

}


bool GamePlayManager::init()
{
    
    
    return true;
}



void GamePlayManager::updateMatrx()
{
    for (int row = 0; row < MAXROW; ++row) {
        for (int col = 0; col < MAXCOL; ++col) {
            
            if (nullptr != starMatrix[row][col]) {
                starMatrix[row][col]->updatePosition();
            }
        }
        
        
    }
    
    
}


void GamePlayManager::initMatrix()
{
    std::srand((unsigned int)std::time(0));
    
    for (int row = 0; row < MAXROW; ++row) {
        for (int col = 0; col < MAXCOL; ++col) {
            int color = abs(rand()%MAXCOLOR - 1);
           // std::string name = Star::getStarColor(color);
            starMatrix[row][col] = Star::create((Star::StarColor)color);
            
            starMatrix[row][col]->setAnchorPoint(Vec2(0.5, 0.5));
            
            CCLOG("width:%f, height:%f", starMatrix[row][col]->getContentSize().width,  starMatrix[row][col]->getContentSize().height);
            // CCLOG("Real width:%f, height:%f", starMatrix[row][col]->getContentSizeIn().width,  starMatrix[row][col]->getContentSize().height);
           
            starMatrix[row][col]->setPosition(getPositionByIndex(row, col) + Point(0,300));
            starMatrix[row][col]->setIndexPath(Point(row, col));
            starMatrix[row][col]->setDestPosition(getPositionByIndex(row, col));
            
            m_layer->addChild(starMatrix[row][col]);
            
            
        }
    }
    
    
    
}


void GamePlayManager::onTouch(const Point &p)
{
    Point touchStar = getTouchOnStar(p);
    
    if (touchStar != Point(-1, -1)) {
        CCLOG("x=%f, y=%f", touchStar.x, touchStar.y);
        std::set<Point> s = std::set<Point>();
        s.insert(Point(touchStar.x, touchStar.y));
        
        std::set<Point> ss = sameColorStar(s);
        
        
        clearSelected();
        
        clearGroupStar(ss);
        
        CCLOG("-----------------------");
     //   std::cout << ss;
        
    } else {
        
        CCLOG("Not touch on star");
    }
    
    
    
}



// 因为设置了缩放因子
Point GamePlayManager::getPositionByIndex(int i,int j){
    float s = Director::getInstance()->getContentScaleFactor();
    float x = j * Star::STARWIDTH + Star::STARWIDTH/2;
    float y = (GamePlayManager::MAXCOL - i)*Star::STARWIDTH - Star::STARHIGHT/2;
    return Point(x / s, y / s);  // s 为 缩放因子
}



/*
    Private function
 */


Point GamePlayManager::getTouchOnStar(const Point &p)
{
    for (int row = 0; row < MAXROW; ++row) {
        for (int col = 0; col < MAXCOL; ++col) {
            if (nullptr != starMatrix[row][col]) {
                Size size =  starMatrix[row][col]->getContentSize();
                Point point = starMatrix[row][col]->getPosition();
                Rect r = Rect(point.x - size.width/2, point.y - size.height/2, size.width, size.height);
                
                if (r.containsPoint(p)) {
                    return Point(row, col);
                }
            }
            
            
        }
    }

    return Point(-1, -1); // Out of stars
    
    
}

std::set<Point> GamePlayManager::sameColorStar(std::set<Point> p)
{
    std::set<Point> result = std::set<Point>();
    
    for (std::set<Point>::iterator it= p.begin(); it != p.end(); ++it) {
        
        int row = (int)it->x;
        int col = (int)it->y;
        
        CCLOG("row=%d, col=%d", row+1, col+1);
        
        Star *star = starMatrix[row][col];
        
        std::set<Point> s = std::set<Point>();
        Star::StarColor color = star->getColor();
        
        
      //  if (!star->isSelected()) {  // Not selected
            // up
        if (row - 1 >= 0 &&
            nullptr != starMatrix[row-1][col] &&
            color == starMatrix[row-1][col]->getColor() &&
            false == starMatrix[row-1][col]->isSelected()) {
            
            s.insert(Point(row-1, col));
            
        }
        
        // down
        if (row + 1 < MAXROW &&
            nullptr != starMatrix[row+1][col] &&
            color == starMatrix[row+1][col]->getColor() &&
            false == starMatrix[row+1][col]->isSelected()) {
            
            s.insert(Point(row+1, col));
            
        }
        
        
        // left
        if (col - 1 >= 0 &&
            nullptr != starMatrix[row][col-1] &&
            color == starMatrix[row][col-1]->getColor() &&
            false == starMatrix[row][col-1]->isSelected()) {
            
            s.insert(Point(row, col-1));
            
        }
        
        
        // right
        if (col + 1 < MAXCOL &&
            nullptr != starMatrix[row][col+1] &&
            color == starMatrix[row][col+1]->getColor() &&
            false == starMatrix[row][col+1]->isSelected()) {
            
            s.insert(Point(row, col+1));
            
        }
        
        
        star->setSelected(true);
        
        
        if (s.empty()) {
            s.insert(*it);
            result.insert(*it);
        } else {
            std::set<Point> r = sameColorStar(s);
            // set return from around
            for (std::set<Point>::iterator it= r.begin(); it != r.end(); ++it) {                result.insert(*it);
            }
        }
        
    }
    
    for (std::set<Point>::iterator it= p.begin(); it != p.end(); ++it) {
        result.insert(*it);
    }

    return result;
}




void GamePlayManager::clearSelected() {
    
    for (int row = 0; row < MAXROW; ++row) {
        for (int col = 0; col < MAXCOL; ++col) {
            if (nullptr != starMatrix[row][col]) {
                starMatrix[row][col]->setSelected(false);
                
//                CCLOG("---------------------------");
//                CCLOG("%d",starMatrix[row][col]->isSelected());
//                
//                 CCLOG("---------------------------");
//                
            }
        }
        
    }
    
}


void GamePlayManager::clearGroupStar(std::set<Point> p)
{
    for (auto it = p.begin(); it != p.end(); ++it) {
        
        int row = (int)(*it).x;
        int col = (int)(*it).y;
        
        starMatrix[row][col]->setVisible(false);
        starMatrix[row][col] = nullptr;
        
        
        
    }
    
    
}
